#include <string.h>
#include"interim.h"

int lab_num = 1;//用于LABEL的命名
int interim_is_error = 0;//程序无错=0，有错=1
InterCode in_head = NULL;//记录双向链表的头部
InterCode in_now = NULL;//记录现在的双向链表节点
extern int temp_num; //对于符号表中的符号，在加入table时就赋予其数字

//测试各个中间代码是否能正常打印到命令行界面
void translate_print_test(InterCode temp) {
    switch (temp->kind) {
        case ILABEL: {
            //LABEL labelx :
            printf("LABEL label");
            printf("%d ", temp->u.ulabel.op->u_int);
            printf(":");
            break;
        }
        case IFUNCTION: {
            //FUNCTION f :
            printf("FUNCTION ");
            printf("%s ", temp->u.ulabel.op->u_char);
            printf(":");
            break;
        }
        case ASSIGN: {
            //有等号的打印
            Operand t1 = temp->u.uassign.op1;
            Operand t2 = temp->u.uassign.op2;
            if (t1 == NULL || t2 == NULL) {
                return;
            } else if (t1->kind == ADDRESS && t2->kind == ADDRESS) {
                //*t1 := *t2
                printf("*t%d", t1->u_int);
                printf(" := ");
                printf("*t%d", t2->u_int);
            } else if (t2->kind == ADDRESS) {
                //t1 := *t2
                printf("t%d", t1->u_int);
                printf(" := ");
                printf("*t%d", t2->u_int);
            } else if (t1->kind == ADDRESS) {
                //&t1 := t2;    &t1 := #5
                printf("&t%d", t1->u_int);
                printf(" := ");
                if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
                else printf("t%d", t2->u_int);
            } else {
                //t1 := t1;     t1 := #5
                printf("t%d", t1->u_int);
                printf(" := ");
                if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
                else printf("t%d", t2->u_int);
            }
            break;
        }
        case ADD: {
            //x := y + z
            Operand t1 = temp->u.ubinop.result;
            Operand t2 = temp->u.ubinop.op1;
            Operand t3 = temp->u.ubinop.op2;
            printf("t%d", t1->u_int);
            printf(" := ");
            if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
            else printf("t%d", t2->u_int);
            printf(" + ");
            if (t3->kind == CONSTANT) printf("#%d", t3->u_int);
            else printf("t%d", t3->u_int);
            break;
        }

        case SUB: {
            //x := y - z
            Operand t1 = temp->u.ubinop.result;
            Operand t2 = temp->u.ubinop.op1;
            Operand t3 = temp->u.ubinop.op2;
            printf("t%d", t1->u_int);
            printf(" := ");
            if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
            else printf("t%d", t2->u_int);
            printf(" - ");
            if (t3->kind == CONSTANT) printf("#%d", t3->u_int);
            else printf("t%d", t3->u_int);
            break;
        }

        case MUL: {
            //x := y * z
            Operand t1 = temp->u.ubinop.result;
            Operand t2 = temp->u.ubinop.op1;
            Operand t3 = temp->u.ubinop.op2;
            printf("t%d", t1->u_int);
            printf(" := ");
            if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
            else printf("t%d", t2->u_int);
            printf(" * ");
            if (t3->kind == CONSTANT) printf("#%d", t3->u_int);
            else printf("t%d", t3->u_int);
            break;
        }

        case DIV: {
            //x := y / z
            Operand t1 = temp->u.ubinop.result;
            Operand t2 = temp->u.ubinop.op1;
            Operand t3 = temp->u.ubinop.op2;
            printf("t%d", t1->u_int);
            printf(" := ");
            if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
            else printf("t%d", t2->u_int);
            printf(" / ");
            if (t3->kind == CONSTANT) printf("#%d", t3->u_int);
            else printf("t%d", t3->u_int);
            break;
        }

        case ADDRESS1: {
            //t1 := &t2
            Operand t1 = temp->u.uassign.op1;
            Operand t2 = temp->u.uassign.op2;
            printf("t%d", t1->u_int);
            printf(" := ");
            printf("&t%d", t2->u_int);
            break;
        }

        case ADDRESS2: {
            // t1 := *t2
            Operand t1 = temp->u.uassign.op1;
            Operand t2 = temp->u.uassign.op2;
            printf("t%d", t1->u_int);
            printf(" := ");
            printf("*t%d", t2->u_int);
            break;
        }

        case ADDRESS3: {
            //*t1 := t2
            Operand t1 = temp->u.uassign.op1;
            Operand t2 = temp->u.uassign.op2;
            printf("*t%d", t1->u_int);
            printf(" := ");
            if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
            else printf("t%d", t2->u_int);
            break;
        }

        case GOTO: {
            //GOTO label1
            printf("GOTO label");
            printf("%d", temp->u.ulabel.op->u_int);
            break;
        }

        case IF: {
            //IF x [relop] y GOTO z
            Operand t1 = temp->u.uif.x;
            Operand re = temp->u.uif.relop;
            Operand t2 = temp->u.uif.y;
            Operand t3 = temp->u.uif.z;
            printf("IF ");
            if (t1->kind == CONSTANT) printf("#%d", t1->u_int);
            else if (t1->kind == ADDRESS) printf("*t%d", t1->u_int);
            else printf("t%d", t1->u_int);

            if (re->u_int == 0) printf(" == ");
            else if (re->u_int == 1) printf(" != ");
            else if (re->u_int == 2) printf(" < ");
            else if (re->u_int == 3) printf(" > ");
            else if (re->u_int == 4) printf(" <= ");
            else if (re->u_int == 5) printf(" >= ");

            if (t2->kind == CONSTANT) printf("#%d", t2->u_int);
            else if (t2->kind == ADDRESS) printf("*t%d", t2->u_int);
            else printf("t%d", t2->u_int);
            printf(" GOTO label");
            printf("%d", t3->u_int);
            break;
        }

        case RETURN: {
            //return x
            printf("RETURN ");
            if (temp->u.ulabel.op->kind == CONSTANT) printf("#%d", temp->u.ulabel.op->u_int);
            else printf("t%d", temp->u.ulabel.op->u_int);
            break;
        }

        case DEC: {
            //DEC x [size]
            printf("DEC ");
            printf("t%d ", temp->u.udec.op->u_int);
            printf("%d", temp->u.udec.size);
            break;
        }

        case ARG: {
            //ARG x
            printf("ARG ");
            if (temp->u.ulabel.op->kind == CONSTANT) printf("#%d", temp->u.ulabel.op->u_int);
            else if (temp->u.ulabel.op->kind == ADDRESS) printf("&t%d", temp->u.ulabel.op->u_int);
            else if (temp->u.ulabel.op->kind == WADDRESS) printf("*t%d", temp->u.ulabel.op->u_int);
            else printf("t%d", temp->u.ulabel.op->u_int);
            break;
        }

        case CALL: {
            //x := CALL f
            Operand t1 = temp->u.uassign.op1;
            Operand t2 = temp->u.uassign.op2;
            if (t1 != NULL) printf("t%d := ", t1->u_int);
            printf("CALL ");
            printf("%s", t2->u_char);
            break;
        }

        case PARAM: {
            //PARAM x
            printf("PARAM ");
            if (temp->u.ulabel.op->kind == CONSTANT) printf("#%d", temp->u.ulabel.op->u_int);
            else printf("t%d", temp->u.ulabel.op->u_int);
            break;
        }

        case READ: {
            //READ x
            printf("READ ");
            if (temp->u.ulabel.op->kind == CONSTANT) printf("#%d", temp->u.ulabel.op->u_int);
            else printf("t%d", temp->u.ulabel.op->u_int);
            break;
        }

        case WRITE: {
            //WRITE x
            printf("WRITE ");
            if (temp->u.ulabel.op->kind == CONSTANT) printf("#%d", temp->u.ulabel.op->u_int);
            else printf("t%d", temp->u.ulabel.op->u_int);
            break;
        }

        default: {
            printf("ERROR!!!\n");
        }

    }
    printf("\n");
}

//将中间代码输出到文件
void translate_print(FILE *f) {
    InterCode temp = in_head;
    int is_null = 0; //用于记录是否出现操作数为空的情况
    while (temp != NULL) {
        switch (temp->kind) {
            case ILABEL: {
                //LABEL x :
                fprintf(f, "LABEL label");
                fprintf(f, "%d ", temp->u.ulabel.op->u_int);
                fprintf(f, ":");
                break;
            }
            case IFUNCTION: {
                //FUNCTION f :
                fprintf(f, "FUNCTION ");
                fprintf(f, "%s ", temp->u.ulabel.op->u_char);
                fprintf(f, ":");
                break;
            }
            case ASSIGN: {
                //等号
                Operand t1 = temp->u.uassign.op1;
                Operand t2 = temp->u.uassign.op2;
                if (t1 == NULL || t2 == NULL) {
                    is_null = 1;
                } else if (t1->kind == ADDRESS && t2->kind == ADDRESS) {
                    // *t1 := *t2
                    fprintf(f, "*t%d", t1->u_int);
                    fprintf(f, " := ");
                    fprintf(f, "*t%d", t2->u_int);
                } else if (t2->kind == ADDRESS) {
                    //t1 := *t2
                    fprintf(f, "t%d", t1->u_int);
                    fprintf(f, " := ");
                    fprintf(f, "*t%d", t2->u_int);
                } else if (t1->kind == ADDRESS) {
                    //&t1 := t2
                    fprintf(f, "&t%d", t1->u_int);
                    fprintf(f, " := ");
                    if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                    else fprintf(f, "t%d", t2->u_int);
                } else {
                    //t1 := t2
                    fprintf(f, "t%d", t1->u_int);
                    fprintf(f, " := ");
                    if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                    else fprintf(f, "t%d", t2->u_int);
                }
                break;
            }
            case ADD: {
                //t1 := t2 + t3
                Operand t1 = temp->u.ubinop.result;
                Operand t2 = temp->u.ubinop.op1;
                Operand t3 = temp->u.ubinop.op2;
                if (t1 == NULL);
                else {
                    fprintf(f, "t%d", t1->u_int);
                    fprintf(f, " := ");
                    if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                    else fprintf(f, "t%d", t2->u_int);
                    fprintf(f, " + ");
                    if (t3->kind == CONSTANT) fprintf(f, "#%d", t3->u_int);
                    else fprintf(f, "t%d", t3->u_int);
                }
                break;
            }
            case SUB: {
                //t1 := t2 - t3
                Operand t1 = temp->u.ubinop.result;
                Operand t2 = temp->u.ubinop.op1;
                Operand t3 = temp->u.ubinop.op2;
                if (t1 == NULL);
                else {
                    fprintf(f, "t%d", t1->u_int);
                    fprintf(f, " := ");
                    if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                    else fprintf(f, "t%d", t2->u_int);
                    fprintf(f, " - ");
                    if (t3->kind == CONSTANT) fprintf(f, "#%d", t3->u_int);
                    else fprintf(f, "t%d", t3->u_int);
                }
                break;
            }
            case MUL: {
                //t1 := t2 * t3
                Operand t1 = temp->u.ubinop.result;
                Operand t2 = temp->u.ubinop.op1;
                Operand t3 = temp->u.ubinop.op2;
                if (t1 == NULL);
                else {
                    fprintf(f, "t%d", t1->u_int);
                    fprintf(f, " := ");
                    if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                    else fprintf(f, "t%d", t2->u_int);
                    fprintf(f, " * ");
                    if (t3->kind == CONSTANT) fprintf(f, "#%d", t3->u_int);
                    else fprintf(f, "t%d", t3->u_int);
                }
                break;
            }
            case DIV: {
                //t1 := t2 / t3
                Operand t1 = temp->u.ubinop.result;
                Operand t2 = temp->u.ubinop.op1;
                Operand t3 = temp->u.ubinop.op2;
                if (t1 == NULL);
                else {
                    fprintf(f, "t%d", t1->u_int);
                    fprintf(f, " := ");
                    if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                    else fprintf(f, "t%d", t2->u_int);
                    fprintf(f, " / ");
                    if (t3->kind == CONSTANT) fprintf(f, "#%d", t3->u_int);
                    else fprintf(f, "t%d", t3->u_int);
                }
                break;
            }
            case ADDRESS1: {
                //t1 := &t2
                Operand t1 = temp->u.uassign.op1;
                Operand t2 = temp->u.uassign.op2;
                fprintf(f, "t%d", t1->u_int);
                fprintf(f, " := ");
                fprintf(f, "&t%d", t2->u_int);
                break;
            }
            case ADDRESS2: {
                //t1 := *t2
                Operand t1 = temp->u.uassign.op1;
                Operand t2 = temp->u.uassign.op2;
                fprintf(f, "t%d", t1->u_int);
                fprintf(f, " := ");
                fprintf(f, "*t%d", t2->u_int);
                break;
            }
            case ADDRESS3: {
                //*t1 := t2
                Operand t1 = temp->u.uassign.op1;
                Operand t2 = temp->u.uassign.op2;
                fprintf(f, "*t%d", t1->u_int);
                fprintf(f, " := ");
                if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                else fprintf(f, "t%d", t2->u_int);
                break;
            }
            case GOTO: {
                //GOTO x
                fprintf(f, "GOTO label");
                fprintf(f, "%d", temp->u.ulabel.op->u_int);
                break;
            }
            case IF: {
                //IF x [relop] y GOTO z
                Operand t1 = temp->u.uif.x;
                Operand re = temp->u.uif.relop;
                Operand t2 = temp->u.uif.y;
                Operand t3 = temp->u.uif.z;
                fprintf(f, "IF ");
                if (t1->kind == CONSTANT) fprintf(f, "#%d", t1->u_int);
                else if (t1->kind == ADDRESS) fprintf(f, "*t%d", t1->u_int);
                else fprintf(f, "t%d", t1->u_int);

                if (re->u_int == 0) fprintf(f, " == ");
                else if (re->u_int == 1) fprintf(f, " != ");
                else if (re->u_int == 2) fprintf(f, " < ");
                else if (re->u_int == 3) fprintf(f, " > ");
                else if (re->u_int == 4) fprintf(f, " <= ");
                else if (re->u_int == 5) fprintf(f, " >= ");

                if (t2->kind == CONSTANT) fprintf(f, "#%d", t2->u_int);
                else if (t2->kind == ADDRESS) fprintf(f, "*t%d", t2->u_int);
                else fprintf(f, "t%d", t2->u_int);
                fprintf(f, " GOTO label");
                fprintf(f, "%d", t3->u_int);
                break;
            }
            case RETURN: {
                //RETURN x
                fprintf(f, "RETURN ");
                if (temp->u.ulabel.op->kind == CONSTANT) fprintf(f, "#%d", temp->u.ulabel.op->u_int);
                else fprintf(f, "t%d", temp->u.ulabel.op->u_int);
                break;
            }
            case DEC: {
                //DEC x [size]
                fprintf(f, "DEC ");
                fprintf(f, "t%d ", temp->u.udec.op->u_int);
                fprintf(f, "%d", temp->u.udec.size);
                break;
            }
            case ARG: {
                //ARG x
                fprintf(f, "ARG ");
                if (temp->u.ulabel.op->kind == CONSTANT) fprintf(f, "#%d", temp->u.ulabel.op->u_int);
                else if (temp->u.ulabel.op->kind == ADDRESS) fprintf(f, "&t%d", temp->u.ulabel.op->u_int);
                else if (temp->u.ulabel.op->kind == WADDRESS) fprintf(f, "*t%d", temp->u.ulabel.op->u_int);
                else fprintf(f, "t%d", temp->u.ulabel.op->u_int);
                break;
            }
            case CALL: {
                //x := CALL f
                Operand t1 = temp->u.uassign.op1;
                Operand t2 = temp->u.uassign.op2;
                if (t1 != NULL) fprintf(f, "t%d := ", t1->u_int);
                else {
                    Operand t0 = new_temp();
                    fprintf(f, "t%d := ", t0->u_int);
                }
                fprintf(f, "CALL ");
                fprintf(f, "%s", t2->u_char);
                break;
            }
            case PARAM: {
                //PARAM x
                fprintf(f, "PARAM ");
                if (temp->u.ulabel.op->kind == CONSTANT) fprintf(f, "#%d", temp->u.ulabel.op->u_int);
                else fprintf(f, "t%d", temp->u.ulabel.op->u_int);
                break;
            }
            case READ: {
                //READ x
                fprintf(f, "READ ");
                if (temp->u.ulabel.op->kind == CONSTANT) fprintf(f, "#%d", temp->u.ulabel.op->u_int);
                else fprintf(f, "t%d", temp->u.ulabel.op->u_int);
                break;
            }
            case WRITE: {
                //WRITE x
                fprintf(f, "WRITE ");
                if (temp->u.ulabel.op->kind == CONSTANT) fprintf(f, "#%d", temp->u.ulabel.op->u_int);
                else fprintf(f, "t%d", temp->u.ulabel.op->u_int);
                break;
            }
            default:
                printf("ERROR!!!\n");
        }
        if (is_null == 0) fprintf(f, "\n");
        else is_null = 0;
        temp = temp->next;
    }
}

//中间代码生成入口函数
void translate_Program(struct Node *now, char *filename) {
    /*
    Program → ExtDecList
    ExtDecList → ExtDef ExtDecList | null
    */
    if (interim_is_error == 1) return;
    //Program → ExtDecList
    struct Node *extdeflist = now->child;
    while (extdeflist->child != NULL) {
        //ExtDecList → ExtDef ExtDecList | null
        struct Node *extdef = extdeflist->child;
        translate_ExtDef(extdef);
        extdeflist = extdef->brother;
    }
    if (interim_is_error == 0) {
        FILE *F = fopen(filename, "w");
        if (!F) {
            perror(filename);
            return;
        }
        translate_print(F);
    }
}

// 全局变量、结构体、函数定义
void translate_ExtDef(struct Node *now) {
    /*
    ExtDef → Specifier ExtDecList SEMI
    | Specifier SEMI
    | Specifier FunDec CompSt
    */
    if (interim_is_error == 1) return;
    struct Node *after_specifier = now->child->brother;
    if (strcmp(after_specifier->name, "FunDec\0") == 0) {
        //Specifier FunDec CompSt
        //函数定义
        translate_FunDec(after_specifier);
        translate_CompSt(after_specifier->brother);
    } else {
        //Specifier SEMI
        //Specifier ExtDecList SEMI
        //由于没有全局变量和结构体的使用，因此只需要检查这两者的出现，然后报出不能翻译的printf输出即可
        translate_Specifier(now->child);
    }
}

// 函数头的定义
void translate_FunDec(struct Node *now) {
    //FunDec → ID LP VarList RP| ID LP RP
    if (interim_is_error == 1) return;
    //ID,构造Operand和InterCode
    Operand func_op = (Operand) malloc(sizeof(struct Operand_));
    func_op->kind = FUNCTION;
    func_op->u_char = now->child->char_name; //函数名
    InterCode func_in = (InterCode) malloc(sizeof(struct InterCode_));
    func_in->kind = IFUNCTION;
    func_in->u.ulabel.op = func_op;
    add_to_intercode(func_in);
    //VarList，参数列表
    if (now->child->brother->brother->brother == NULL) return; //无参数
    struct FUNCTION *find_func = find_in_function(now->child->char_name);
    FieldList func_field = find_func->field;
    while (func_field != NULL) {
        //1.每一个参数生成一个对应的operand，根据结构体、非结构体设置kind
        if (func_field->type->kind == ARRAY) {
            // 数组作为参数
            printf("Cannot translate: A parameter of an array appears.\n");
            interim_is_error = 1;
            return;
        }
        if (func_field->type->kind == STRUCTURE) {
            // 结构体作为参数
            printf("Cannot translate: A variable or a parameter of a struct appears.\n");
            interim_is_error = 1;
            return;
        }
        Operand field_op = (Operand) malloc(sizeof(struct Operand_));
        field_op->kind = VARIABLE;
        //记录用户给的名称，以及符号表中赋变量后面的数字
        struct TABLE *find_it = find_symbol_in_table(func_field->name);
        field_op->u_char = func_field->name;
        field_op->u_int = find_it->variable;
        //2.每个参数生成一条中间代码
        InterCode field_in = (InterCode) malloc(sizeof(struct InterCode_));
        field_in->kind = PARAM;
        field_in->u.ulabel.op = field_op;
        add_to_intercode(field_in);
        //下一个参数
        func_field = func_field->tail;
    }
}

//函数体
void translate_CompSt(struct Node *now) {
    //CompSt → LC DefList StmtList RC
    if (interim_is_error == 1) return;
    struct Node *deflist = now->child->brother;
    struct Node *stmtlist = deflist->brother;
    translate_DefList(deflist);
    translate_StmtList(stmtlist);
    return;
}

// 0个或者多个def; 如:int a; float b,c ;int d[10];
void translate_DefList(struct Node *now) {
    //DefList → Def DefList| null
    if (interim_is_error == 1) return;
    struct Node *newdef = now->child;
    while (newdef != NULL) {
        translate_Def(newdef);
        newdef = newdef->brother->child;
    }
}

// 0个或者多个stmt,表示多个语句
void translate_StmtList(struct Node *now) {
    //StmtList → Stmt StmtList| null
    if (interim_is_error == 1) return;
    struct Node *child = now->child;
    while (child != NULL) {
        translate_Stmt(child);
        child = child->brother->child;
    }
}

// 变量定义
void translate_Def(struct Node *now) {
    //Def → Specifier DecList SEMI
    if (interim_is_error == 1) return;
    struct Node *declist = now->child->brother;
    translate_DecList(declist);
}

// 语句
void translate_Stmt(struct Node *now) {
    /*
    Stmt → Exp SEMI
    | CompSt
    | RETURN Exp SEMI
    | IF LP Exp RP Stmt
    | IF LP Exp RP Stmt ELSE Stmt
    | WHILE LP Exp RP Stmt
    */
    if (interim_is_error == 1) return;
    struct Node *child = now->child;
    if (strcmp(child->name, "Exp\0") == 0) {
        //Stmt → Exp SEMI
        translate_Exp(now->child, NULL);
    } else if (strcmp(child->name, "CompSt\0") == 0) {
        //Stmt →CompSt
        translate_CompSt(now->child);
    } else if (strcmp(child->name, "RETURN\0") == 0) {
        //Stmt →RETURN Exp SEMI
        Operand t1 = new_temp();
        translate_Exp(now->child->brother, t1);
        Operand t0 = NULL;
        if (t1->kind == ADDRESS) {
            // 返回值是地址变量,需要处理
            t0 = new_temp();
            InterCode code0_in = (InterCode) malloc(sizeof(struct InterCode_));
            code0_in->kind = ADDRESS2;
            code0_in->u.uassign.op1 = t0;
            code0_in->u.uassign.op2 = t1;
            add_to_intercode(code0_in);
        }
        InterCode return_in = (InterCode) malloc(sizeof(struct InterCode_));
        return_in->kind = RETURN;
        if (t0 == NULL) return_in->u.ulabel.op = t1;
        else return_in->u.ulabel.op = t0;
        add_to_intercode(return_in);
    } else if (strcmp(child->name, "IF\0") == 0) {
        //Stmt →IF LP Exp RP Stmt|IF LP Exp RP Stmt ELSE Stmt
        //见实验3pdf第20页
        struct Node *else_node = child->brother->brother->brother->brother->brother;
        if (else_node == NULL) {
            //Stmt →IF LP Exp RP Stmt
            Operand l1 = new_label();
            Operand l2 = new_label();
            translate_Cond(child->brother->brother, l1, l2);
            InterCode l1_in = (InterCode) malloc(sizeof(struct InterCode_));
            l1_in->kind = ILABEL;
            l1_in->u.ulabel.op = l1;
            add_to_intercode(l1_in);
            translate_Stmt(child->brother->brother->brother->brother);
            InterCode l2_in = (InterCode) malloc(sizeof(struct InterCode_));
            l2_in->kind = ILABEL;
            l2_in->u.ulabel.op = l2;
            add_to_intercode(l2_in);
            return;
        } else {
            //IF LP Exp RP Stmt ELSE Stmt
            Operand l1 = new_label();
            Operand l2 = new_label();
            Operand l3 = new_label();
            //code1
            translate_Cond(child->brother->brother, l1, l2);
            //LABEL l1
            InterCode l1_in = (InterCode) malloc(sizeof(struct InterCode_));
            l1_in->kind = ILABEL;
            l1_in->u.ulabel.op = l1;
            add_to_intercode(l1_in);
            //code2
            translate_Stmt(child->brother->brother->brother->brother);
            //GOTO label3
            InterCode l2_in = (InterCode) malloc(sizeof(struct InterCode_));
            l2_in->kind = GOTO;
            l2_in->u.ulabel.op = l3;
            add_to_intercode(l2_in);
            //LABEL l2
            InterCode l3_in = (InterCode) malloc(sizeof(struct InterCode_));
            l3_in->kind = ILABEL;
            l3_in->u.ulabel.op = l2;
            add_to_intercode(l3_in);
            //code3
            translate_Stmt(child->brother->brother->brother->brother->brother->brother);
            //LABEL l3
            InterCode l4_in = (InterCode) malloc(sizeof(struct InterCode_));
            l4_in->kind = ILABEL;
            l4_in->u.ulabel.op = l3;
            add_to_intercode(l4_in);
            return;
        }
    } else if (strcmp(child->name, "WHILE\0") == 0) {
        //Stmt →WHILE LP Exp RP Stmt
        ////见实验3pdf第20页
        Operand l1 = new_label();
        Operand l2 = new_label();
        Operand l3 = new_label();
        //LABEL L1
        InterCode l1_in = (InterCode) malloc(sizeof(struct InterCode_));
        l1_in->kind = ILABEL;
        l1_in->u.ulabel.op = l1;
        add_to_intercode(l1_in);
        //code1
        translate_Cond(child->brother->brother, l2, l3);
        //LABEL l2
        InterCode l3_in = (InterCode) malloc(sizeof(struct InterCode_));
        l3_in->kind = ILABEL;
        l3_in->u.ulabel.op = l2;
        add_to_intercode(l3_in);
        //code2
        translate_Stmt(child->brother->brother->brother->brother);
        //GOTO label1
        InterCode l2_in = (InterCode) malloc(sizeof(struct InterCode_));
        l2_in->kind = GOTO;
        l2_in->u.ulabel.op = l1;
        add_to_intercode(l2_in);
        //LABEL l3
        InterCode l4_in = (InterCode) malloc(sizeof(struct InterCode_));
        l4_in->kind = ILABEL;
        l4_in->u.ulabel.op = l3;
        add_to_intercode(l4_in);
    } else {
        printf("EORRO!!!\n");
    }
}

//0个或者多个dec,如int a,b,c
void translate_DecList(struct Node *now) {
    //DecList → Dec| Dec COMMA DecList
    if (interim_is_error == 1) return;
    struct Node *child = now->child;
    translate_Dec(child);
    struct Node *comma = child->brother;
    if (comma == NULL);//DecList → Dec
    else translate_DecList(comma->brother);//DecList →Dec COMMA DecList
}

//表达式
void translate_Exp(struct Node *now, Operand place) {
    /*
     EXP → Exp ASSIGNOP Exp
        | Exp AND Exp
        | Exp OR Exp
        | Exp RELOP Exp
        | Exp PLUS Exp
        | Exp MINUS Exp
        | Exp STAT Exp
        | Exp DIV Exp
        | LP Exp RP
        | MINUS Exp
        | NOT Exp
        | ID LP Args RP
        | ID LP RP
        | Exp LB Exp RB
        | Exp DOT ID
        | ID
        | INT
        | FLOAT
    */
    // place是引用传参，可以在本函数修改单条代码Operand，在函数返回后值也会更着改变
    if (interim_is_error == 1) return;
    struct Node *child = now->child;
    struct Node *fir_bro = child->brother;
    if (fir_bro == NULL) {
        /*
        | ID
        | INT
        | FLOAT
        */
        if (strcmp(child->name, "INT\0") == 0) {
            //Exp → INT
            int value = child->int_number;
            if (place == NULL) return;
            place->kind = CONSTANT;
            place->u_int = value;
            return;
        } else if (strcmp(child->name, "ID\0") == 0) {
            //Exp → ID
            //这里也可能出现结构体以及数组，均返回address
            //如op.x=1因此要考虑
            struct TABLE *find_id = find_symbol_in_table(child->char_name);
            char *name = child->char_name;
            if (place == NULL) return;
            if (find_id->is_from_func == 0 && find_id->field->type->kind != BASIC) {
                //引用类型,类型改为地址
                place->kind = ADDRESS;
            } else {
                place->kind = VARIABLE;
            }
            place->u_char = name;
            place->u_int = find_id->variable;
            place->type = find_id->field->type;
            return;
        } else {
            // 假设1：不会出现注释、八进制或十六进制整型常数、浮点型常数或者变量。
            // 因此没有Exp->FLOAT
            printf("ERROR!!!\n");
        }
    }
    struct Node *sec_bro = fir_bro->brother;
    if (sec_bro == NULL) {
        /*
        | MINUS Exp
        | NOT Exp
        */
        if (strcmp(child->name, "MINUS\0") == 0) {
            //Exp → MINUS Exp
            if (place == NULL) return;
            Operand t1 = new_temp();
            translate_Exp(child->brother, t1);
            InterCode minus_in = (InterCode) malloc(sizeof(struct InterCode_));
            minus_in->kind = SUB;
            minus_in->u.ubinop.result = place;
            minus_in->u.ubinop.op2 = t1;
            Operand t2 = (Operand) malloc(sizeof(struct Operand_));
            t2->kind = CONSTANT;
            t2->u_int = 0;
            minus_in->u.ubinop.op1 = t2;
            if (place->kind == FROM_ARG) place->kind = VARIABLE;
            add_to_intercode(minus_in);
            return;
        } else if (strcmp(child->name, "NOT\0") == 0) {
            //Exp →NOT Exp
            //TODO
            Operand l1 = new_label();
            Operand l2 = new_label();
            //code0
            InterCode code0_in = (InterCode) malloc(sizeof(struct InterCode_));
            code0_in->kind = ASSIGN;
            code0_in->u.uassign.op1 = place;
            Operand t1 = (Operand) malloc(sizeof(struct Operand_));
            t1->kind = CONSTANT;
            t1->u_int = 0;
            code0_in->u.uassign.op2 = t1;
            add_to_intercode(code0_in);
            //code1
            translate_Cond(now, l1, l2);
            //code2-1
            InterCode code2_in = (InterCode) malloc(sizeof(struct InterCode_));
            code2_in->kind = ILABEL;
            code2_in->u.ulabel.op = l1;
            add_to_intercode(code2_in);
            //code2-2
            InterCode code22_in = (InterCode) malloc(sizeof(struct InterCode_));
            code22_in->kind = ASSIGN;
            code22_in->u.uassign.op1 = place;
            Operand t2 = (Operand) malloc(sizeof(struct Operand_));
            t2->kind = CONSTANT;
            t2->u_int = 1;
            code22_in->u.uassign.op2 = t2;
            add_to_intercode(code22_in);
            //LABEL l2
            InterCode label_in = (InterCode) malloc(sizeof(struct InterCode_));
            label_in->kind = ILABEL;
            label_in->u.ulabel.op = l2;
            add_to_intercode(label_in);
            return;
        }
    }
    if (strcmp(fir_bro->name, "ASSIGNOP\0") == 0) {
        //Exp → Exp ASSIGNOP Exp
        if(strcmp(child->child->name,"ID\0")==0){
            //左侧的exp是由ID生成
            Operand t1=new_temp();
            //code1
            translate_Exp(fir_bro->brother,t1);
            //code21
            InterCode code21_in=(InterCode)malloc(sizeof(struct InterCode_));
            code21_in->kind=ASSIGN;
            code21_in->u.uassign.op2=t1;
            Operand t2=(Operand)malloc(sizeof(struct Operand_));
            struct TABLE* find_it=find_symbol_in_table(child->child->char_name);
            t2->kind=VARIABLE;
            t2->u_char=child->child->char_name;
            t2->u_int=find_it->variable;
            code21_in->u.uassign.op1=t2;
            add_to_intercode(code21_in);
            //code22
            InterCode code22_in=(InterCode)malloc(sizeof(struct InterCode_));
            code22_in->kind=ASSIGN;
            code22_in->u.uassign.op1=place;
            code22_in->u.uassign.op2=t2;
            add_to_intercode(code22_in);
            return;
        }
        else{
            //左侧的exp是不由ID生成
            Operand t1=new_temp();
            //code1
            translate_Exp(fir_bro->brother,t1);
            Operand t0=NULL;
            if(t1->kind==ADDRESS){
                //t0=*t1
                t0=new_temp();
                InterCode in_1=(InterCode)malloc(sizeof(struct InterCode_));
                in_1->kind=ADDRESS2;
                in_1->u.uassign.op1=t0;
                in_1->u.uassign.op2=t1;
                add_to_intercode(in_1);
            }
            //code21
            InterCode code21_in=(InterCode)malloc(sizeof(struct InterCode_));
            code21_in->kind=ADDRESS3;
            if(t0==NULL) {
                //*t2 := t1
                code21_in->u.uassign.op2=t1;
            }
            else {
                //*t2 := t0 = *t1
                code21_in->u.uassign.op2=t0;
            }
            Operand t2=new_temp();
            translate_Exp(child,t2);
            code21_in->u.uassign.op1=t2;
            add_to_intercode(code21_in);
            //code22
            InterCode code22_in=(InterCode)malloc(sizeof(struct InterCode_));
            code22_in->kind=ASSIGN;
            code22_in->u.uassign.op1=place;
            code22_in->u.uassign.op2=t2;
            add_to_intercode(code22_in);
            return;
        }
    }
    if (strcmp(fir_bro->name, "AND\0") == 0 || strcmp(fir_bro->name, "OR\0") == 0 ||
        strcmp(fir_bro->name, "RELOP\0") == 0) {
        //Exp → Exp AND\OR\RELOP Exp
        Operand l1 = new_label();
        Operand l2 = new_label();
        //code0
        InterCode code0_in = (InterCode) malloc(sizeof(struct InterCode_));
        code0_in->kind = ASSIGN;
        code0_in->u.uassign.op1 = place;
        Operand t1 = (Operand) malloc(sizeof(struct Operand_));
        t1->kind = CONSTANT;
        t1->u_int = 0;
        code0_in->u.uassign.op2 = t1;
        add_to_intercode(code0_in);
        //code1
        translate_Cond(now, l1, l2);
        //code2-1
        InterCode code2_in = (InterCode) malloc(sizeof(struct InterCode_));
        code2_in->kind = ILABEL;
        code2_in->u.ulabel.op = l1;
        add_to_intercode(code2_in);
        //code2-2
        InterCode code22_in = (InterCode) malloc(sizeof(struct InterCode_));
        code22_in->kind = ASSIGN;
        code22_in->u.uassign.op1 = place;
        Operand t2 = (Operand) malloc(sizeof(struct Operand_));
        t2->kind = CONSTANT;
        t2->u_int = 1;
        code22_in->u.uassign.op2 = t2;
        add_to_intercode(code22_in);
        //LABEL l2
        InterCode label_in = (InterCode) malloc(sizeof(struct InterCode_));
        label_in->kind = ILABEL;
        label_in->u.ulabel.op = l2;
        add_to_intercode(label_in);
        return;
    }
    if (strcmp(fir_bro->name, "PLUS\0") == 0 || strcmp(fir_bro->name, "MINUS\0") == 0 ||
        strcmp(fir_bro->name, "STAR\0") == 0 || strcmp(fir_bro->name, "DIV\0") == 0) {
        /*
         Exp → Exp PLUS Exp
            → Exp MINUS Exp
            → Exp STAR Exp
            → Exp DIV Exp
        */
        Operand t1 = new_temp();
        Operand t2 = new_temp();
        //code1
        translate_Exp(child, t1);
        //code2
        translate_Exp(fir_bro->brother, t2);
        Operand t3 = NULL;
        Operand t4 = NULL;
        if (t1->kind == CONSTANT && t2->kind == CONSTANT) {
            //如果都是常量
            place->kind = VARIABLE;
        } else {
            if (t1->kind == ADDRESS) {
                //如果t1是地址
                //t3 := *t1
                t3 = new_temp();
                InterCode in1 = (InterCode) malloc(sizeof(struct InterCode_));
                in1->kind = ADDRESS2;
                in1->u.uassign.op1 = t3;
                in1->u.uassign.op2 = t1;
                add_to_intercode(in1);
            }
            if (t2->kind == ADDRESS) {
                //如果t2是地址
                //t4 := *t2
                t4 = new_temp();
                InterCode in1 = (InterCode) malloc(sizeof(struct InterCode_));
                in1->kind = ADDRESS2;
                in1->u.uassign.op1 = t4;
                in1->u.uassign.op2 = t2;
                add_to_intercode(in1);
            }
        }
        InterCode code0_in = (InterCode) malloc(sizeof(struct InterCode_));
        if (strcmp(fir_bro->name, "PLUS\0") == 0) {
            code0_in->kind = ADD;
        } else if (strcmp(fir_bro->name, "MINUS\0") == 0) {
            code0_in->kind = SUB;
        } else if (strcmp(fir_bro->name, "STAR\0") == 0) {
            code0_in->kind = MUL;
        } else if (strcmp(fir_bro->name, "DIV\0") == 0) {
            code0_in->kind = DIV;
        } else {
            printf("ERROR!!!\n");
        }
        code0_in->u.ubinop.result = place;
        if (t3 == NULL) code0_in->u.ubinop.op1 = t1;
        else code0_in->u.ubinop.op1 = t3;
        if (t4 == NULL) code0_in->u.ubinop.op2 = t2;
        else code0_in->u.ubinop.op2 = t4;
        add_to_intercode(code0_in);
        return;
    }
    if (strcmp(fir_bro->name, "DOT\0") == 0) {
        //Exp → Exp DOT ID,结构体
        printf("Cannot translate: A variable or a parameter of a struct appears.\n");
        interim_is_error = 1;
        return;
    }
    if (strcmp(fir_bro->name, "LB\0") == 0) {
        //Exp → Exp LB Exp RB
        //数组，但是只能为1维数组
        //获取数组的首地址
        Operand t1 = new_temp();
        translate_Exp(child, t1);
        //t1 := &t0;取出首地址
        Operand t0 = new_temp();
        t0->kind = ADDRESS;
        InterCode in = (InterCode) malloc(sizeof(struct InterCode_));
        in->kind = ADDRESS1;
        in->u.uassign.op1 = t0;
        in->u.uassign.op2 = t1;
        add_to_intercode(in);
        //获取数组单个单位的长度offset
        int offset = get_offset(t1->type);
        if (offset == -1) return; //出现高维度数组
        //生成t2=offset*i
        Operand i = new_temp();
        translate_Exp(fir_bro->brother, i);
        Operand t2 = new_temp();
        Operand o_offset = (Operand) malloc(sizeof(struct Operand_));
        o_offset->kind = CONSTANT;
        o_offset->u_int = offset;
        InterCode in2 = (InterCode) malloc(sizeof(struct InterCode_));
        in2->kind = MUL;
        in2->u.ubinop.result = t2;
        in2->u.ubinop.op1 = i;
        in2->u.ubinop.op2 = o_offset;
        add_to_intercode(in2);
        //4.生成中间代码t3=t1+t2
        if (place == NULL) return;
        if (place->kind == FROM_ARG) {
            //数组某元素传入函数，应该传入值
            place->kind = WADDRESS;//*t
        }
        else {
            //其余情况传入地址
            place->kind = ADDRESS;//&t
        }
        place->type = t1->type->u.array.elem;
        InterCode code0_in = (InterCode) malloc(sizeof(struct InterCode_));
        code0_in->kind = ADD;
        code0_in->u.ubinop.result = place;
        code0_in->u.ubinop.op1 = t0;
        code0_in->u.ubinop.op2 = t2;
        add_to_intercode(code0_in);
        return;
    }
    if (strcmp(fir_bro->name, "Exp\0") == 0) {
        //Exp → LP Exp RP
        translate_Exp(fir_bro, place);
        return;
    }
    if (strcmp(sec_bro->name, "Args\0") == 0) {
        //Exp → ID LP Args RP
        //有参数的函数调用
        //0.判断是否为write
        char *function_name = child->char_name;
        if (strcmp(function_name, "write") == 0) {
            Operand t1 = new_temp();
            translate_Exp(sec_bro->child, t1);
            Operand t0 = NULL;
            if (t1->kind == ADDRESS) {
                //要对地址类的取地址处理
                // t0 = *t1
                t0 = new_temp();
                InterCode code0_in = (InterCode) malloc(sizeof(struct InterCode_));
                code0_in->kind = ADDRESS2;
                code0_in->u.uassign.op1 = t0;
                code0_in->u.uassign.op2 = t1;
                add_to_intercode(code0_in);
            }
            InterCode code1_in = (InterCode) malloc(sizeof(struct InterCode_));
            code1_in->kind = WRITE;
            if (t0 == NULL) code1_in->u.ulabel.op = t1;
            else code1_in->u.ulabel.op = t0;
            add_to_intercode(code1_in);
            return;
        }
        //1.ARG传递参数，逆序;递归
        translate_Args(sec_bro, NULL);
        //1.2创建函数的operand
        Operand func_ope = (Operand) malloc(sizeof(struct Operand_));
        func_ope->kind = FUNCTION;
        func_ope->u_char = function_name;
        //2.place=CALL FUNCTION,保存返回值
        InterCode code1_in = (InterCode) malloc(sizeof(struct InterCode_));
        code1_in->kind = CALL;
        code1_in->u.uassign.op1 = place;
        code1_in->u.uassign.op2 = func_ope;
        add_to_intercode(code1_in);
        return;
    }
    if (strcmp(sec_bro->name, "RP\0") == 0) {
        //Exp → ID LP RP
        //没有参数的函数调用
        //0.区分是否为read
        char *function_name = child->char_name;
        if (strcmp(function_name, "read") == 0) {
            InterCode code1_in = (InterCode) malloc(sizeof(struct InterCode_));
            code1_in->kind = READ;
            code1_in->u.ulabel.op = place;
            add_to_intercode(code1_in);
            return;
        }
        //1.2创建函数的operand
        Operand func_ope = (Operand) malloc(sizeof(struct Operand_));
        func_ope->kind = FUNCTION;
        func_ope->u_char = function_name;
        //2.place=CALL FUNCTION,保存返回值
        InterCode code1_in = (InterCode) malloc(sizeof(struct InterCode_));
        code1_in->kind = CALL;
        code1_in->u.uassign.op1 = place;
        code1_in->u.uassign.op2 = func_ope;
        add_to_intercode(code1_in);
        return;
    }
}
//条件表达式的翻译
void translate_Cond(struct Node *now, Operand lt, Operand lf) {
    //lt: label_true,lf: label_false
    /*
     Exp → Exp RELOP Exp
        → Not Exp
        → Exp AND Exp
        → Exp OR Exp
    */
    if (interim_is_error == 1) return;
    struct Node *child = now->child;

    if (child->brother != NULL && strcmp(child->brother->name, "RELOP\0") == 0) {
        //Exp → Exp RELOP Exp
        Operand t1 = new_temp();
        Operand t2 = new_temp();
        //code1+code2
        translate_Exp(child, t1);
        translate_Exp(child->brother->brother, t2);
        Operand op = (Operand) malloc(sizeof(struct Operand_));
        op->kind = RELOP;
        op->u_int = child->brother->linenumber;
        //code3
        InterCode code3 = (InterCode) malloc(sizeof(struct InterCode_));
        code3->kind = IF;
        code3->u.uif.x = t1;
        code3->u.uif.relop = op;
        code3->u.uif.y = t2;
        code3->u.uif.z = lt;
        add_to_intercode(code3);
        //goto labelfalse
        InterCode code4 = (InterCode) malloc(sizeof(struct InterCode_));
        code4->kind = GOTO;
        code4->u.ulabel.op = lf;
        add_to_intercode(code4);
    } else if (strcmp(child->name, "NOT\0") == 0) {
        //Not Exp
        translate_Cond(now->child->brother, lf, lt);
    } else if (child->brother != NULL && strcmp(child->brother->name, "AND\0") == 0) {
        //Exp AND Exp
        Operand l1 = new_label();
        //code1
        translate_Cond(child, l1, lf);
        //label1
        InterCode code1 = (InterCode) malloc(sizeof(struct InterCode_));
        code1->kind = ILABEL;
        code1->u.ulabel.op = l1;
        add_to_intercode(code1);
        //code2
        translate_Cond(child->brother->brother, lt, lf);
    } else if (child->brother != NULL && strcmp(child->brother->name, "OR\0") == 0) {
        //Exp OR Exp
        Operand l1 = new_label();
        //code1
        translate_Cond(child, lt, l1);
        //label1
        InterCode code1 = (InterCode) malloc(sizeof(struct InterCode_));
        code1->kind = ILABEL;
        code1->u.ulabel.op = l1;
        add_to_intercode(code1);
        //code2
        translate_Cond(child->brother->brother, lt, lf);
    } else {
        //other cases
        Operand t1 = new_temp();
        //code1
        translate_Exp(now, t1);
        //code2
        Operand op = (Operand) malloc(sizeof(struct Operand_));
        op->kind = RELOP;
        op->u_int = 1;
        Operand t2 = (Operand) malloc(sizeof(struct Operand_));
        t2->kind = CONSTANT;
        t2->u_int = 0;
        InterCode code2 = (InterCode) malloc(sizeof(struct InterCode_));
        code2->kind = IF;
        code2->u.uif.x = t1;
        code2->u.uif.relop = op;
        code2->u.uif.y = t2;
        code2->u.uif.z = lt;
        add_to_intercode(code2);
        //goto
        InterCode code4 = (InterCode) malloc(sizeof(struct InterCode_));
        code4->kind = GOTO;
        code4->u.ulabel.op = lf;
        add_to_intercode(code4);
    }
    return;
}
//变量定义，如:int a; int a = 5;
void translate_Dec(struct Node *now) {
    //Dec → VarDec| VarDec ASSIGNOP Exp
    if (interim_is_error == 1) return;
    struct Node *vardec = now->child;
    struct Node *fir_bro = vardec->brother;
    if (fir_bro == NULL) {
        //VarDec
        //int a;
        Operand t1 = new_temp();
        translate_VarDec(vardec, t1);
    } else {
        //VarDec ASSIGNOP Exp
        //int a = 5;
        Operand rem1 = new_temp();
        Operand rem2 = new_temp();
        translate_VarDec(vardec, rem1);
        translate_Exp(fir_bro->brother, rem2);

        InterCode func_in = (InterCode) malloc(sizeof(struct InterCode_));
        func_in->kind = ASSIGN;
        func_in->u.uassign.op1 = rem1;
        func_in->u.uassign.op2 = rem2;
        add_to_intercode(func_in);
    }
}
//变量定义，如:int a
void translate_VarDec(struct Node *now, Operand place) {
    //VarDec → ID| VarDec LB INT RB
    if (interim_is_error == 1) return;
    if (now->child->brother == NULL) {
        //VarDec → ID
        struct TABLE *find_it = find_symbol_in_table(now->child->char_name);
        FieldList find_field = find_it->field;
        if (find_field->type->kind == BASIC) {
            if (place == NULL) return;
            place->kind = VARIABLE;
            place->u_int = find_it->variable;
            place->u_char = now->child->char_name;
            return;
        } else if (find_field->type->kind == STRUCTURE) {
            printf("Cannot translate: A variable or a parameter of a struct appears.\n");
            interim_is_error = 1;
            return;
        } else{
            printf("ERROR!!!\n");
            return;
        }
    } else {
        //VarDec LB INT RB
        //只会出现一维数组
        //出现多维数组，输出error
        if (strcmp(now->child->child->name, "ID\0") != 0) {
            interim_is_error = 1;
            printf("Cannot translate: A variable of high-dimensional array (an array higher than 1 dimension) appears.\n");
            interim_is_error = 1;
            return;
        }
        //一维数组
        if (place == NULL) return;
        place->kind = VARIABLE;
        place->u_char = now->child->char_name;
        struct TABLE *find_it = find_symbol_in_table(now->child->child->char_name);
        place->u_int = find_it->variable;
        //生成DEC语句,申请数组的空间
        InterCode func_in = (InterCode) malloc(sizeof(struct InterCode_));
        func_in->kind = DEC;
        func_in->u.udec.op = place;
        func_in->u.udec.size = get_size(find_it->field->type);
        add_to_intercode(func_in);
        return;
    }
}
//函数参数的翻译
void translate_Args(struct Node *now, InterCode here) {
    //Args → Exp COMMA Args| Exp
    if (interim_is_error == 1) return;

    struct Node *exp = now->child;
    //翻译exp信息
    Operand t1 = new_temp();
    t1->kind = FROM_ARG;// FROM_ARG用于判断是否为传递给exp的arg(参数)
    translate_Exp(exp, t1);
    if (!(t1->kind == CONSTANT || t1->kind == ADDRESS || t1->kind == WADDRESS)) {
        //如果类型是变量
        struct TABLE *find_id = find_symbol_in_table(t1->u_char);
        if (find_id == NULL) {
            //中间代码产生的中间变量temp,在用户的符号表中找不到
            t1->kind=VARIABLE;
        }
        else if (find_id->field->type->kind != BASIC) {
            //传递的如果是数组a[0]，则是一个address类型,需要修改kind类型
            //不是普通类型，就改为地址类型
            t1->kind = ADDRESS;
        }
        else {
            t1->kind = VARIABLE;
        }
    }
    //生成ARG传参语句
    InterCode code1_in = (InterCode) malloc(sizeof(struct InterCode_));
    code1_in->kind = ARG;
    code1_in->u.ulabel.op = t1;
    //将语句连接到语句双向链表中
    if (here == NULL) {
        code1_in->next = NULL;
        code1_in->before = NULL;
    } else {
        here->next = code1_in;
        code1_in->before = here;
    }
    exp = exp->brother;
    if (exp != NULL){
        //Exp COMMA Args
        translate_Args(exp->brother, code1_in);
    }
    //逆序传参
    if (here == NULL) {
        InterCode temp = code1_in;
        while (temp->next != NULL) temp = temp->next;
        while (temp != NULL) {
            InterCode rem = temp;
            temp = temp->before;
            add_to_intercode(rem);
        }
    }
}
//类型描述符
void translate_Specifier(struct Node *now) {
    //Specifier → TYPE| StructSpecifier
    if (interim_is_error == 1) return;
    //Specifier → TYPE 不需要产生中间代码
    //StructSpecifier
    if (strcmp(now->child->name, "StructSpecifier") == 0) {
        translate_StructSpecifier(now->child);
    }
}
//结构体
void translate_StructSpecifier(struct Node *now) {
    //StructSpecifier → STRUCT OptTag LC DefList RC| STRUCT Tag
    printf("Cannot translate: A variable or a parameter of a struct appears.\n");
    interim_is_error = 1;
    return;
}
//将代码加入中间代码双向链表
void add_to_intercode(InterCode interCode) {
    interCode->before = NULL;
    interCode->next = NULL;
    if (in_head == NULL) {
        in_head = interCode;
    }
    if (in_now == NULL) {
        in_now = interCode;
    } else {
        in_now->next = interCode;
        interCode->before = in_now;
        in_now = interCode;
    }
}
//新建一个代码Operand
Operand new_temp() {
    Operand now = (Operand) malloc(sizeof(struct Operand_));
    now->kind = TEMP;
    now->u_int = temp_num;
    now->u_char = "temp\0";
    temp_num++;
    return now;
}
//新建一个LEBEL符号
Operand new_label() {
    Operand now = (Operand) malloc(sizeof(struct Operand_));
    now->kind = LABEL;
    now->u_int = lab_num;
    lab_num++;
    return now;
}
//计算数组偏移
int get_offset(Type return_type) {
    if (return_type == NULL) {
        return 0;
    }
    else if (return_type->kind == BASIC) {
        return 4;
    }
    else if (return_type->kind == ARRAY) {
        //只有一维数组，多出一维都报错
        if (return_type->u.array.elem->kind == ARRAY) {
            interim_is_error = 1;
            printf("Cannot translate: A variable of high-dimensional array (an array higher than 1 dimension) appears.\n");
            interim_is_error = 1;
            return -1;
        }
        //返回该数组单个元素的长度
        int offset = 0;
        Type elem = return_type->u.array.elem;
        offset = get_size(elem);
        return offset;
    }
}
//计算全部偏移，即type中的所有内存都要加上
int get_size(Type type) {
    if (type == NULL) return 0;
    if (type->kind == BASIC) return 4;
    else if (type->kind == ARRAY) {
        //只有一维数组
        int temp = type->u.array.size * get_size(type->u.array.elem);
        return temp;
    } else if (type->kind == STRUCTURE) {
        printf("Cannot translate: A variable or a parameter of a struct appears.\n");
        interim_is_error = 1;
        return;
    }
}
